package edu.jhu.cs.oose.scheduleit.services.impl;


import java.util.List;
import org.springframework.dao.DataAccessException;
import edu.jhu.cs.oose.scheduleit.dao.EventDao;
import edu.jhu.cs.oose.scheduleit.dao.ScheduleDao;
import edu.jhu.cs.oose.scheduleit.services.EventService;
import edu.jhu.cs.oose.scheduleit.util.Attribute;
import edu.jhu.cs.oose.scheduleit.util.DateWrapper;
import edu.jhu.cs.oose.scheduleit.util.EventAttributeKind;
import edu.jhu.cs.oose.scheduleit.util.EventType;
import edu.jhu.cs.oose.scheduleit.vo.Event;
import edu.jhu.cs.oose.scheduleit.vo.Schedule;
import edu.jhu.cs.oose.scheduleit.vo.User;

/**
 * The implementation class of the EventService interface
 * @author oosegroup2
 *
 */
public class EventServiceImpl implements EventService {

	
	/**
	 * The data access object related to schedule
	 */
	private ScheduleDao scheduleDao;
	
	/**
	 * The data access object related to event
	 */
	private EventDao eventDao;
	
	/**
	 * The setter for field scheduleDao
	 * @param scheduleDao
	 */
	public void setScheduleDao(ScheduleDao scheduleDao) {
		this.scheduleDao = scheduleDao;
	}

	/**
	 * The setter for field eventDao
	 * @param eventDao
	 */
 	public void setEventDao(EventDao eventDao) {
		this.eventDao = eventDao;
	}
	
	@Override
	public void addEvent(Schedule schedule, Event event)
			throws DataBaseException {
		try {
			if (!this.eventDao.getEvents(schedule).contains(event)){
				this.scheduleDao.addEvent(schedule, event);
			}
		} catch (Exception e) {
			throw new DataBaseException(e);
		}

	}

	@Override
	public Event createNewEvent(User user, Schedule schedule,
			Attribute attribute) throws DataBaseException {
		try {
			Object value = null;
			Event event = new Event();
			event.setAuthor(user.getUserInfo());
			event.setContainer(schedule);
			event.setStartTime((DateWrapper)attribute.getValue(EventAttributeKind.START_TIME));
			event.setEndTime((DateWrapper)attribute.getValue(EventAttributeKind.END_TIME));
			
			value = attribute.getValue(EventAttributeKind.DESCRIPTION);
			if (value != null){
				event.setDescription((String) value);
			}else{
				event.setDescription("");
			}
			
			value = attribute.getValue(EventAttributeKind.TYPE);
			if (value != null){
				event.setType((EventType)value);
			}else{
				event.setType(EventType.VIEW);
			}

			this.eventDao.save(event);
			this.scheduleDao.addEvent(schedule, event);
			return event;
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	@Override
	public Event getEvent(int eventID) throws DataBaseException {
		try {
			return this.eventDao.getEvent(eventID);
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	@Override
	public int getEventCount(Schedule schedule, DateWrapper startTime, DateWrapper endTime)
			throws DataBaseException {
		try {
			return this.eventDao.count(schedule, startTime, endTime);
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	public int getEventCount(Schedule schedule) throws DataBaseException{
		try {
			return this.eventDao.count(schedule);
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}
	
	@Override
	public List<Event> getEvents(Schedule schedule, DateWrapper startTime,
			DateWrapper endTime) throws DataBaseException {
		try {
			return this.eventDao.getEvents(schedule, startTime, endTime);
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	public List<Event> getEvents(Schedule schedule) throws DataBaseException{
		try {
			return this.eventDao.getEvents(schedule);
		} catch (DataAccessException e) {
			throw new DataBaseException(e);
		}
	}
	@Override
	public void joinEvent(Event event, User user) throws DataBaseException {
		try {
			this.eventDao.addJoinedUser(event, user.getUserInfo());
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	@Override
	public void quitEvent(Event event, User user) throws DataBaseException {
		try {
			this.eventDao.removeJoinedUser(event, user.getUserInfo());
		} catch (Exception e) {
			throw new DataBaseException(e);
		}

	}

	@Override
	public void removeEvent(Schedule schedule, Event event)
			throws DataBaseException {
		try {
			this.scheduleDao.removeEvent(schedule, event);
			if (event.getContainer().equals(schedule)){
				this.eventDao.deleteEvent(event);
			}
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

	@Override
	public void updateEvent(Event event) throws DataBaseException {
		try {
			this.eventDao.save(event);
		} catch (Exception e) {
			throw new DataBaseException(e);
		}
	}

}
